Data Summary
income <- read.csv("https://ecoleman451.github.io/website/Data%20Visualization/Datasets/income_per_person.csv")
life <- read.csv("https://ecoleman451.github.io/website/Data%20Visualization/Datasets/life_expectancy_years.csv")
# Reshape data set such that there are only three columns (Geo, Year, & Income)
new_income <- pivot_longer(income, cols = -geo, names_to = "year", values_to = "income")
new_life <- pivot_longer(life, cols = -geo, names_to = "year", values_to = "life.expectancy")
## Create new data set
LifeExpIncom <- merge(new_life, new_income, by = c("geo", "year"))
## Read in More Data
country <- read.csv("https://ecoleman451.github.io/website/Data%20Visualization/Datasets/countries_total.csv")
pop <- read.csv("https://ecoleman451.github.io/website/Data%20Visualization/Datasets/population_total.csv")
new_pop <- pivot_longer(pop, cols = -geo, names_to = "year", values_to = "population")
## Merge LifeExpIncom with Country
merged <- merge(LifeExpIncom, country, by.x = "geo", by.y = "name", all.x = TRUE)
## Merge Population with Merged Data
fin_data <- merge(new_pop, merged, by = c("geo", "year"), all.x = TRUE)
## Get Data for Year 2000
final_data <- subset(fin_data, year =="X2000")
We first read in two datasets called “income” and “life,” which
represent income and life expectancy values over many years. “Income”
has 193 observations with 220 total variables, while “Life” has 187
observations and 220 total variables. Next, we reshape both datasets to
have only three columns: Geo, Year, and Income or Life Expectancy. We
then merge these reshaped sets into a dataset called “LifeExpIncome,”
which now contains Geo, Year, Income, and Life Expectancy (40953
observations and 4 variables). Next, we read in two more datasets:
“country” (240 observations and 11 variables) and “pop” (195
observations and 220 variables), representing country and population
data, respectively. We reshape “pop” to align with “LifeExpIncome” and
“Country,” which already have Year transformed into a single column.
After this, we merge “LifeExpIncome” with “Country” and then merge this
newly combined set with the reshaped “pop” set, creating a dataset
called “fin_data” (42705 observations and 15 variables). Finally, we
subset the data to focus only on data from the year 2000, resulting in
our “final_data” set (195 observations and 15 variables):
GGPlot
The scatter plot below shows the relationship between income, life
expectancy, and population size across different regions in the year
2000. Each point represents a country, with the size of the points
corresponding to the population size of that specific region. The
countries are color-coded for better visualization.
scatter_pop <- ggplot(final_data, aes(x = life.expectancy, y = income, color = region, size = population)) +
geom_point() +
labs(title = "Life Expectancy vs. Income per Region (2000)",
x = "Life Expectancy",
y = "Income",
size = "Population",
color = "Region")
scatter_pop
From the plot, we observe a slightly positive correlation between income
and life expectancy. It indicates that countries with higher incomes are
likely to have longer life expectancies. Additionally, countries in the
Americas and Asia tend to have larger populations, as indicated by the
larger point sizes. This also suggests that countries with higher
populations might have longer life expectancies. European countries
appear to have the longest life expectancies, with most of their points
on the far right side of the graph, although their populations are not
as large as those of other regions. Next, we subset the data to focus on
the year 2015, resulting in our “final_data” set (195 observations and
15 variables). Now, let’s examine the overall summary statistics for the
dataset “fin_data,” which includes data from all years, not just
2015.
## Get Data for Year 2015
final_data <- subset(fin_data, year =="X2015")
Plotly
The plot below shows the relationship between income, life
expectancy, and population size across different regions over several
years. Each point represents a country, with the size of the points
corresponding to the population size of that specific country. The
countries are color-coded by region for better visualization. To make
the plot more visually appealing, we’ve applied a transformation to the
population size using a logarithmic function. This transformation
compresses the range of population sizes, reducing the size of the
points and making the plot clearer and easier to interpret.
Additionally, the x-axis uses a logarithmic scale to better visualize
the wide range of income values. The plot is animated to show how these
relationships change over time, providing a dynamic view of global
trends in income, life expectancy, and population:
pal.IBM <- c("#332288", "#117733", "#0072B2","#D55E00", "#882255")
pal.IBM <- setNames(pal.IBM, c("Asia", "Europe", "Africa", "Americas", "Oceania"))
# Ensure no NA values in the region column
final_data <- final_data %>%
filter(!is.na(region)) # Remove rows with NA in the region column
# Filter data to remove NA values and convert year to numeric
final_data$year <- as.numeric(gsub("X", "", final_data$year))
final_data <- final_data %>%
filter(!is.na(life.expectancy) & !is.na(income) & !is.na(population))
fig <- final_data %>%
plot_ly(
x = ~income,
y = ~life.expectancy,
size = ~(2*log(population)-11)^2,
color = ~region,
colors = pal.IBM, # custom colors
frame = ~year, # the time variable to
text = ~paste("Country:", geo,
"<br>Region:", region,
"<br>Year:", year,
"<br>Life Expectancy:", life.expectancy,
"<br>Population:", population,
"<br>Income per Person:", income),
hoverinfo = "text",
type = 'scatter',
mode = 'markers'
)
fig <- fig %>% layout(
xaxis = list(
type = "log"
),
title = "Income vs. Life Expectancy Over Time",
xaxis = list(title = "Income per Person (Log Scale)"),
yaxis = list(title = "Life Expectancy")
)
fig
The x-axis represents the income levels for each country, with higher
incomes positioned further to the right. The y-axis represents life
expectancy, with higher life expectancies positioned higher on the axis.
From the plot, we can observe that some countries dominate the scatter
plot due to their larger population sizes and higher incomes. This
visualization allows us to analyze whether countries with higher incomes
generally have longer life expectancies. Additionally, we can examine
whether there is a correlation between population size and income
levels, helping to identify trends and patterns in the data.
In the animated plot, each frame corresponds to a different year,
showing how the relationship between income, life expectancy, and
population size evolves over time. The size of each point is determined
by the population of the country, with larger points indicating larger
populations. The color of the points indicates the region to which the
country belongs, allowing us to see regional trends and differences more
clearly. By observing the animation, we can identify how economic and
health outcomes have changed across different regions and time periods,
providing insights into global development patterns.
LS0tDQp0aXRsZTogIkdHUGxvdCAmIFBsb3RseSINCmF1dGhvcjogIkVkd2FyZCBDb2xlbWFuIg0KZGF0ZTogIjAyLTIyLTIwMjQiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBmaWdfd2lkdGg6IDYNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICB0aGVtZTogcmVhZGFibGUNCiAgICBmaWdfaGVpZ2h0OiA0DQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtY29sb3I6bGlnaHRncmF5Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCiAgICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgICBjb2xvcjogIzc4MGMwYzsNCn0NCg0KLyogbW91c2Ugb3ZlciBsaW5rICovDQpkaXYjVE9DIGE6aG92ZXIgew0KICBjb2xvcjogcmVkOw0KfQ0KDQovKiB1bnZpc2l0ZWQgbGluayAqLw0KZGl2I1RPQyBhOmxpbmsgew0KICBjb2xvcjogYmx1ZTsNCn0NCg0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDI0cHg7DQogIGNvbG9yOiBEYXJrYmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgZm9udC12YXJpYW50LWNhcHM6IG5vcm1hbDsNCn0NCmg0LmF1dGhvciB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgew0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogZGFya3JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogZGFya3JlZDsNCiAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogdW52aXNpdGVkIGxpbmsgKi8NCmE6bGluayB7DQogIGNvbG9yOiBncmVlbjsNCn0NCg0KLyogdmlzaXRlZCBsaW5rICovDQphOnZpc2l0ZWQgew0KICBjb2xvcjogZ3JlZW47DQp9DQoNCi8qIG1vdXNlIG92ZXIgbGluayAqLw0KYTpob3ZlciB7DQogIGNvbG9yOiByZWQ7DQp9DQoNCi8qIHNlbGVjdGVkIGxpbmsgKi8NCmE6YWN0aXZlIHsNCiAgY29sb3I6IHllbGxvdzsNCn0NCg0KPC9zdHlsZT4NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0UsIGNvbW1lbnQ9TkF9DQpvcHRpb25zKHJlcG9zID0gbGlzdChDUkFOPSJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iKSkNCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgiY293cGxvdCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikNCiAgIGxpYnJhcnkoY293cGxvdCkNCn0NCmlmICghcmVxdWlyZSgibGF0ZXgyZXhwIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImxhdGV4MmV4cCIpDQogICBsaWJyYXJ5KGxhdGV4MmV4cCkNCn0NCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogICBsaWJyYXJ5KHBsb3RseSkNCn0NCmlmICghcmVxdWlyZSgiZ2FwbWluZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImdhcG1pbmRlciIpDQogICBsaWJyYXJ5KGdhcG1pbmRlcikNCn0NCmlmICghcmVxdWlyZSgicG5nIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJwbmciKSAgICANCiAgICBsaWJyYXJ5KCJwbmciKQ0KfQ0KaWYgKCFyZXF1aXJlKCJSQ3VybCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiUkN1cmwiKSAgICANCiAgICBsaWJyYXJ5KCJSQ3VybCIpDQp9DQppZiAoIXJlcXVpcmUoImNvbG91cnBpY2tlciIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiY29sb3VycGlja2VyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImNvbG91cnBpY2tlciIpDQp9DQppZiAoIXJlcXVpcmUoImdnYW5pbWF0ZSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdnYW5pbWF0ZSIpDQp9DQppZiAoIXJlcXVpcmUoImdpZnNraSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2lmc2tpIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdpZnNraSIpDQp9DQppZiAoIXJlcXVpcmUoIm1hZ2ljayIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibWFnaWNrIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoIm1hZ2ljayIpDQp9DQppZiAoIXJlcXVpcmUoImdyRGV2aWNlcyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ3JEZXZpY2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdyRGV2aWNlcyIpDQp9DQppZiAoIXJlcXVpcmUoImpwZWciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImpwZWciKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgianBlZyIpDQp9DQppZiAoIXJlcXVpcmUoImdncmlkZ2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ3JpZGdlcyIpDQp9DQppZiAoIXJlcXVpcmUoInBseXIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBseXIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgicGx5ciIpDQp9DQppZiAoIXJlcXVpcmUoImdnaXJhcGgiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdnaXJhcGgiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dpcmFwaCIpDQp9DQppZiAoIXJlcXVpcmUoImhpZ2hjaGFydGVyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJoaWdoY2hhcnRlciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJoaWdoY2hhcnRlciIpDQp9DQppZiAoIXJlcXVpcmUoImZvcmVjYXN0IikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJmb3JlY2FzdCIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJmb3JlY2FzdCIpDQp9DQppZiAoIXJlcXVpcmUoImxlYWZsZXQiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImxlYWZsZXQiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibGVhZmxldCIpDQp9DQppZiAoIXJlcXVpcmUoInNmIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJzZiIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJzZiIpDQp9DQppZiAoIXJlcXVpcmUoIlN0YXQyRGF0YSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJTdGF0MkRhdGEiKQ0KICAgbGlicmFyeShTdGF0MkRhdGEpDQp9DQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgZWNobyA9IFRSVUUsICAgICAgIA0KICB3YXJuaW5nID0gRkFMU0UsICAgDQogIHJlc3VsdCA9IFRSVUUsICAgDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgY29tbWVudCA9IE5BDQopDQoNCmxpYnJhcnkoY29sb3JzcGFjZSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dmb3JjZSkNCmxpYnJhcnkoZ2dyaWRnZXMpDQpsaWJyYXJ5KHRyZWVtYXBpZnkpDQpsaWJyYXJ5KGZvcmNhdHMpDQpsaWJyYXJ5KHN0YXRlYmlucykNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KGNvd3Bsb3QpDQoNCm9wdGlvbnMoZGlnaXRzID0gMykNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgZWNobyA9IFRSVUUsDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLA0KICBjYWNoZSA9IEZBTFNFLA0KICBmaWcuYWxpZ24gPSAnY2VudGVyJywNCiAgZmlnLndpZHRoID0gNiwNCiAgZmlnLmFzcCA9IDAuNjE4LA0KICBmaWcuc2hvdyA9ICJob2xkIg0KKQ0Kb3B0aW9ucyhkcGx5ci5wcmludF9taW4gPSA2LCBkcGx5ci5wcmludF9tYXggPSA2KQ0KYGBgDQoNCiMgRGF0YSBTdW1tYXJ5DQpgYGB7cn0NCmluY29tZSA8LSByZWFkLmNzdigiaHR0cHM6Ly9lY29sZW1hbjQ1MS5naXRodWIuaW8vd2Vic2l0ZS9EYXRhJTIwVmlzdWFsaXphdGlvbi9EYXRhc2V0cy9pbmNvbWVfcGVyX3BlcnNvbi5jc3YiKQ0KDQpsaWZlIDwtIHJlYWQuY3N2KCJodHRwczovL2Vjb2xlbWFuNDUxLmdpdGh1Yi5pby93ZWJzaXRlL0RhdGElMjBWaXN1YWxpemF0aW9uL0RhdGFzZXRzL2xpZmVfZXhwZWN0YW5jeV95ZWFycy5jc3YiKQ0KDQojIFJlc2hhcGUgZGF0YSBzZXQgc3VjaCB0aGF0IHRoZXJlIGFyZSBvbmx5IHRocmVlIGNvbHVtbnMgKEdlbywgWWVhciwgJiBJbmNvbWUpDQpuZXdfaW5jb21lIDwtIHBpdm90X2xvbmdlcihpbmNvbWUsIGNvbHMgPSAtZ2VvLCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gImluY29tZSIpDQoNCm5ld19saWZlIDwtIHBpdm90X2xvbmdlcihsaWZlLCBjb2xzID0gLWdlbywgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJsaWZlLmV4cGVjdGFuY3kiKQ0KDQojIyBDcmVhdGUgbmV3IGRhdGEgc2V0DQpMaWZlRXhwSW5jb20gPC0gbWVyZ2UobmV3X2xpZmUsIG5ld19pbmNvbWUsIGJ5ID0gYygiZ2VvIiwgInllYXIiKSkNCg0KIyMgUmVhZCBpbiBNb3JlIERhdGENCmNvdW50cnkgPC0gcmVhZC5jc3YoImh0dHBzOi8vZWNvbGVtYW40NTEuZ2l0aHViLmlvL3dlYnNpdGUvRGF0YSUyMFZpc3VhbGl6YXRpb24vRGF0YXNldHMvY291bnRyaWVzX3RvdGFsLmNzdiIpDQoNCnBvcCA8LSByZWFkLmNzdigiaHR0cHM6Ly9lY29sZW1hbjQ1MS5naXRodWIuaW8vd2Vic2l0ZS9EYXRhJTIwVmlzdWFsaXphdGlvbi9EYXRhc2V0cy9wb3B1bGF0aW9uX3RvdGFsLmNzdiIpDQoNCm5ld19wb3AgPC0gcGl2b3RfbG9uZ2VyKHBvcCwgY29scyA9IC1nZW8sIG5hbWVzX3RvID0gInllYXIiLCB2YWx1ZXNfdG8gPSAicG9wdWxhdGlvbiIpDQoNCiMjIE1lcmdlIExpZmVFeHBJbmNvbSB3aXRoIENvdW50cnkNCm1lcmdlZCA8LSBtZXJnZShMaWZlRXhwSW5jb20sIGNvdW50cnksIGJ5LnggPSAiZ2VvIiwgYnkueSA9ICJuYW1lIiwgYWxsLnggPSBUUlVFKQ0KDQojIyBNZXJnZSBQb3B1bGF0aW9uIHdpdGggTWVyZ2VkIERhdGENCmZpbl9kYXRhIDwtIG1lcmdlKG5ld19wb3AsIG1lcmdlZCwgYnkgPSBjKCJnZW8iLCAieWVhciIpLCBhbGwueCA9IFRSVUUpDQoNCiMjIEdldCBEYXRhIGZvciBZZWFyIDIwMDANCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbl9kYXRhLCB5ZWFyID09IlgyMDAwIikNCmBgYA0KICBXZSBmaXJzdCByZWFkIGluIHR3byBkYXRhc2V0cyBjYWxsZWQgImluY29tZSIgYW5kICJsaWZlLCIgd2hpY2ggcmVwcmVzZW50IGluY29tZSBhbmQgbGlmZSBleHBlY3RhbmN5IHZhbHVlcyBvdmVyIG1hbnkgeWVhcnMuICJJbmNvbWUiIGhhcyAxOTMgb2JzZXJ2YXRpb25zIHdpdGggMjIwIHRvdGFsIHZhcmlhYmxlcywgd2hpbGUgIkxpZmUiIGhhcyAxODcgb2JzZXJ2YXRpb25zIGFuZCAyMjAgdG90YWwgdmFyaWFibGVzLiBOZXh0LCB3ZSByZXNoYXBlIGJvdGggZGF0YXNldHMgdG8gaGF2ZSBvbmx5IHRocmVlIGNvbHVtbnM6IEdlbywgWWVhciwgYW5kIEluY29tZSBvciBMaWZlIEV4cGVjdGFuY3kuIFdlIHRoZW4gbWVyZ2UgdGhlc2UgcmVzaGFwZWQgc2V0cyBpbnRvIGEgZGF0YXNldCBjYWxsZWQgIkxpZmVFeHBJbmNvbWUsIiB3aGljaCBub3cgY29udGFpbnMgR2VvLCBZZWFyLCBJbmNvbWUsIGFuZCBMaWZlIEV4cGVjdGFuY3kgKDQwOTUzIG9ic2VydmF0aW9ucyBhbmQgNCB2YXJpYWJsZXMpLiANCk5leHQsIHdlIHJlYWQgaW4gdHdvIG1vcmUgZGF0YXNldHM6ICJjb3VudHJ5IiAoMjQwIG9ic2VydmF0aW9ucyBhbmQgMTEgdmFyaWFibGVzKSBhbmQgInBvcCIgKDE5NSBvYnNlcnZhdGlvbnMgYW5kIDIyMCB2YXJpYWJsZXMpLCByZXByZXNlbnRpbmcgY291bnRyeSBhbmQgcG9wdWxhdGlvbiBkYXRhLCByZXNwZWN0aXZlbHkuIFdlIHJlc2hhcGUgInBvcCIgdG8gYWxpZ24gd2l0aCAiTGlmZUV4cEluY29tZSIgYW5kICJDb3VudHJ5LCIgd2hpY2ggYWxyZWFkeSBoYXZlIFllYXIgdHJhbnNmb3JtZWQgaW50byBhIHNpbmdsZSBjb2x1bW4uIEFmdGVyIHRoaXMsIHdlIG1lcmdlICJMaWZlRXhwSW5jb21lIiB3aXRoICJDb3VudHJ5IiBhbmQgdGhlbiBtZXJnZSB0aGlzIG5ld2x5IGNvbWJpbmVkIHNldCB3aXRoIHRoZSByZXNoYXBlZCAicG9wIiBzZXQsIGNyZWF0aW5nIGEgZGF0YXNldCBjYWxsZWQgImZpbl9kYXRhIiAoNDI3MDUgb2JzZXJ2YXRpb25zIGFuZCAxNSB2YXJpYWJsZXMpLiBGaW5hbGx5LCB3ZSBzdWJzZXQgdGhlIGRhdGEgdG8gZm9jdXMgb25seSBvbiBkYXRhIGZyb20gdGhlIHllYXIgMjAwMCwgcmVzdWx0aW5nIGluIG91ciAiZmluYWxfZGF0YSIgc2V0ICgxOTUgb2JzZXJ2YXRpb25zIGFuZCAxNSB2YXJpYWJsZXMpOg0KDQojIEdHUGxvdA0KICBUaGUgc2NhdHRlciBwbG90IGJlbG93IHNob3dzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUsIGxpZmUgZXhwZWN0YW5jeSwgYW5kIHBvcHVsYXRpb24gc2l6ZSBhY3Jvc3MgZGlmZmVyZW50IHJlZ2lvbnMgaW4gdGhlIHllYXIgMjAwMC4gRWFjaCBwb2ludCByZXByZXNlbnRzIGEgY291bnRyeSwgd2l0aCB0aGUgc2l6ZSBvZiB0aGUgcG9pbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBvcHVsYXRpb24gc2l6ZSBvZiB0aGF0IHNwZWNpZmljIHJlZ2lvbi4gVGhlIGNvdW50cmllcyBhcmUgY29sb3ItY29kZWQgZm9yIGJldHRlciB2aXN1YWxpemF0aW9uLg0KYGBge3J9DQpzY2F0dGVyX3BvcCA8LSBnZ3Bsb3QoZmluYWxfZGF0YSwgYWVzKHggPSBsaWZlLmV4cGVjdGFuY3ksIHkgPSBpbmNvbWUsIGNvbG9yID0gcmVnaW9uLCBzaXplID0gcG9wdWxhdGlvbikpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgbGFicyh0aXRsZSA9ICJMaWZlIEV4cGVjdGFuY3kgdnMuIEluY29tZSBwZXIgUmVnaW9uICgyMDAwKSIsDQogICAgICAgeCA9ICJMaWZlIEV4cGVjdGFuY3kiLA0KICAgICAgIHkgPSAiSW5jb21lIiwNCiAgICAgICBzaXplID0gIlBvcHVsYXRpb24iLA0KICAgICAgIGNvbG9yID0gIlJlZ2lvbiIpDQpzY2F0dGVyX3BvcA0KYGBgDQogIEZyb20gdGhlIHBsb3QsIHdlIG9ic2VydmUgYSBzbGlnaHRseSBwb3NpdGl2ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGluY29tZSBhbmQgbGlmZSBleHBlY3RhbmN5LiBJdCBpbmRpY2F0ZXMgdGhhdCBjb3VudHJpZXMgd2l0aCBoaWdoZXIgaW5jb21lcyBhcmUgbGlrZWx5IHRvIGhhdmUgbG9uZ2VyIGxpZmUgZXhwZWN0YW5jaWVzLiBBZGRpdGlvbmFsbHksIGNvdW50cmllcyBpbiB0aGUgQW1lcmljYXMgYW5kIEFzaWEgdGVuZCB0byBoYXZlIGxhcmdlciBwb3B1bGF0aW9ucywgYXMgaW5kaWNhdGVkIGJ5IHRoZSBsYXJnZXIgcG9pbnQgc2l6ZXMuIFRoaXMgYWxzbyBzdWdnZXN0cyB0aGF0IGNvdW50cmllcyB3aXRoIGhpZ2hlciBwb3B1bGF0aW9ucyBtaWdodCBoYXZlIGxvbmdlciBsaWZlIGV4cGVjdGFuY2llcy4gRXVyb3BlYW4gY291bnRyaWVzIGFwcGVhciB0byBoYXZlIHRoZSBsb25nZXN0IGxpZmUgZXhwZWN0YW5jaWVzLCB3aXRoIG1vc3Qgb2YgdGhlaXIgcG9pbnRzIG9uIHRoZSBmYXIgcmlnaHQgc2lkZSBvZiB0aGUgZ3JhcGgsIGFsdGhvdWdoIHRoZWlyIHBvcHVsYXRpb25zIGFyZSBub3QgYXMgbGFyZ2UgYXMgdGhvc2Ugb2Ygb3RoZXIgcmVnaW9ucy4NCglOZXh0LCB3ZSBzdWJzZXQgdGhlIGRhdGEgdG8gZm9jdXMgb24gdGhlIHllYXIgMjAxNSwgcmVzdWx0aW5nIGluIG91ciAiZmluYWxfZGF0YSIgc2V0ICgxOTUgb2JzZXJ2YXRpb25zIGFuZCAxNSB2YXJpYWJsZXMpLiBOb3csIGxldOKAmXMgZXhhbWluZSB0aGUgb3ZlcmFsbCBzdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHRoZSBkYXRhc2V0ICJmaW5fZGF0YSwiIHdoaWNoIGluY2x1ZGVzIGRhdGEgZnJvbSBhbGwgeWVhcnMsIG5vdCBqdXN0IDIwMTUuDQpgYGB7ciwgY29tbWVudD1OQX0NCiMjIEdldCBEYXRhIGZvciBZZWFyIDIwMTUNCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbl9kYXRhLCB5ZWFyID09IlgyMDE1IikNCmBgYA0KDQojIFBsb3RseQ0KICBUaGUgcGxvdCBiZWxvdyBzaG93cyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gaW5jb21lLCBsaWZlIGV4cGVjdGFuY3ksIGFuZCBwb3B1bGF0aW9uIHNpemUgYWNyb3NzIGRpZmZlcmVudCByZWdpb25zIG92ZXIgc2V2ZXJhbCB5ZWFycy4gRWFjaCBwb2ludCByZXByZXNlbnRzIGEgY291bnRyeSwgd2l0aCB0aGUgc2l6ZSBvZiB0aGUgcG9pbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBvcHVsYXRpb24gc2l6ZSBvZiB0aGF0IHNwZWNpZmljIGNvdW50cnkuIFRoZSBjb3VudHJpZXMgYXJlIGNvbG9yLWNvZGVkIGJ5IHJlZ2lvbiBmb3IgYmV0dGVyIHZpc3VhbGl6YXRpb24uIFRvIG1ha2UgdGhlIHBsb3QgbW9yZSB2aXN1YWxseSBhcHBlYWxpbmcsIHdlJ3ZlIGFwcGxpZWQgYSB0cmFuc2Zvcm1hdGlvbiB0byB0aGUgcG9wdWxhdGlvbiBzaXplIHVzaW5nIGEgbG9nYXJpdGhtaWMgZnVuY3Rpb24uIFRoaXMgdHJhbnNmb3JtYXRpb24gY29tcHJlc3NlcyB0aGUgcmFuZ2Ugb2YgcG9wdWxhdGlvbiBzaXplcywgcmVkdWNpbmcgdGhlIHNpemUgb2YgdGhlIHBvaW50cyBhbmQgbWFraW5nIHRoZSBwbG90IGNsZWFyZXIgYW5kIGVhc2llciB0byBpbnRlcnByZXQuIEFkZGl0aW9uYWxseSwgdGhlIHgtYXhpcyB1c2VzIGEgbG9nYXJpdGhtaWMgc2NhbGUgdG8gYmV0dGVyIHZpc3VhbGl6ZSB0aGUgd2lkZSByYW5nZSBvZiBpbmNvbWUgdmFsdWVzLiBUaGUgcGxvdCBpcyBhbmltYXRlZCB0byBzaG93IGhvdyB0aGVzZSByZWxhdGlvbnNoaXBzIGNoYW5nZSBvdmVyIHRpbWUsIHByb3ZpZGluZyBhIGR5bmFtaWMgdmlldyBvZiBnbG9iYWwgdHJlbmRzIGluIGluY29tZSwgbGlmZSBleHBlY3RhbmN5LCBhbmQgcG9wdWxhdGlvbjoNCmBgYHtyLCBjb21tZW50PU5BfQ0KcGFsLklCTSA8LSBjKCIjMzMyMjg4IiwgIiMxMTc3MzMiLCAiIzAwNzJCMiIsIiNENTVFMDAiLCAiIzg4MjI1NSIpDQpwYWwuSUJNIDwtIHNldE5hbWVzKHBhbC5JQk0sIGMoIkFzaWEiLCAiRXVyb3BlIiwgIkFmcmljYSIsICJBbWVyaWNhcyIsICJPY2VhbmlhIikpDQoNCiMgRW5zdXJlIG5vIE5BIHZhbHVlcyBpbiB0aGUgcmVnaW9uIGNvbHVtbg0KZmluYWxfZGF0YSA8LSBmaW5hbF9kYXRhICU+JQ0KICBmaWx0ZXIoIWlzLm5hKHJlZ2lvbikpICAjIFJlbW92ZSByb3dzIHdpdGggTkEgaW4gdGhlIHJlZ2lvbiBjb2x1bW4NCg0KIyBGaWx0ZXIgZGF0YSB0byByZW1vdmUgTkEgdmFsdWVzIGFuZCBjb252ZXJ0IHllYXIgdG8gbnVtZXJpYw0KZmluYWxfZGF0YSR5ZWFyIDwtIGFzLm51bWVyaWMoZ3N1YigiWCIsICIiLCBmaW5hbF9kYXRhJHllYXIpKQ0KZmluYWxfZGF0YSA8LSBmaW5hbF9kYXRhICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGxpZmUuZXhwZWN0YW5jeSkgJiAhaXMubmEoaW5jb21lKSAmICFpcy5uYShwb3B1bGF0aW9uKSkNCg0KZmlnIDwtIGZpbmFsX2RhdGEgJT4lDQogIHBsb3RfbHkoDQogICAgeCA9IH5pbmNvbWUsIA0KICAgIHkgPSB+bGlmZS5leHBlY3RhbmN5LCANCiAgICBzaXplID0gfigyKmxvZyhwb3B1bGF0aW9uKS0xMSleMiwNCiAgICBjb2xvciA9IH5yZWdpb24sIA0KICAgIGNvbG9ycyA9IHBhbC5JQk0sICAgIyBjdXN0b20gY29sb3JzDQogICAgZnJhbWUgPSB+eWVhciwgICAgICAjIHRoZSB0aW1lIHZhcmlhYmxlIHRvDQogICAgdGV4dCA9IH5wYXN0ZSgiQ291bnRyeToiLCBnZW8sDQogICAgICAgICAgICAgICAgICAiPGJyPlJlZ2lvbjoiLCByZWdpb24sDQogICAgICAgICAgICAgICAgICAiPGJyPlllYXI6IiwgeWVhciwNCiAgICAgICAgICAgICAgICAgICI8YnI+TGlmZSBFeHBlY3RhbmN5OiIsIGxpZmUuZXhwZWN0YW5jeSwNCiAgICAgICAgICAgICAgICAgICI8YnI+UG9wdWxhdGlvbjoiLCBwb3B1bGF0aW9uLA0KICAgICAgICAgICAgICAgICAgIjxicj5JbmNvbWUgcGVyIFBlcnNvbjoiLCBpbmNvbWUpLA0KICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwNCiAgICB0eXBlID0gJ3NjYXR0ZXInLA0KICAgIG1vZGUgPSAnbWFya2VycycNCiAgKQ0KZmlnIDwtIGZpZyAlPiUgbGF5b3V0KA0KICAgIHhheGlzID0gbGlzdCgNCiAgICAgIHR5cGUgPSAibG9nIg0KICAgICksDQogICAgdGl0bGUgPSAiSW5jb21lIHZzLiBMaWZlIEV4cGVjdGFuY3kgT3ZlciBUaW1lIiwNCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiSW5jb21lIHBlciBQZXJzb24gKExvZyBTY2FsZSkiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTGlmZSBFeHBlY3RhbmN5IikNCiAgKQ0KDQpmaWcNCmBgYA0KDQpUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIGluY29tZSBsZXZlbHMgZm9yIGVhY2ggY291bnRyeSwgd2l0aCBoaWdoZXIgaW5jb21lcyBwb3NpdGlvbmVkIGZ1cnRoZXIgdG8gdGhlIHJpZ2h0LiBUaGUgeS1heGlzIHJlcHJlc2VudHMgbGlmZSBleHBlY3RhbmN5LCB3aXRoIGhpZ2hlciBsaWZlIGV4cGVjdGFuY2llcyBwb3NpdGlvbmVkIGhpZ2hlciBvbiB0aGUgYXhpcy4gRnJvbSB0aGUgcGxvdCwgd2UgY2FuIG9ic2VydmUgdGhhdCBzb21lIGNvdW50cmllcyBkb21pbmF0ZSB0aGUgc2NhdHRlciBwbG90IGR1ZSB0byB0aGVpciBsYXJnZXIgcG9wdWxhdGlvbiBzaXplcyBhbmQgaGlnaGVyIGluY29tZXMuIFRoaXMgdmlzdWFsaXphdGlvbiBhbGxvd3MgdXMgdG8gYW5hbHl6ZSB3aGV0aGVyIGNvdW50cmllcyB3aXRoIGhpZ2hlciBpbmNvbWVzIGdlbmVyYWxseSBoYXZlIGxvbmdlciBsaWZlIGV4cGVjdGFuY2llcy4gQWRkaXRpb25hbGx5LCB3ZSBjYW4gZXhhbWluZSB3aGV0aGVyIHRoZXJlIGlzIGEgY29ycmVsYXRpb24gYmV0d2VlbiBwb3B1bGF0aW9uIHNpemUgYW5kIGluY29tZSBsZXZlbHMsIGhlbHBpbmcgdG8gaWRlbnRpZnkgdHJlbmRzIGFuZCBwYXR0ZXJucyBpbiB0aGUgZGF0YS4NCg0KSW4gdGhlIGFuaW1hdGVkIHBsb3QsIGVhY2ggZnJhbWUgY29ycmVzcG9uZHMgdG8gYSBkaWZmZXJlbnQgeWVhciwgc2hvd2luZyBob3cgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGluY29tZSwgbGlmZSBleHBlY3RhbmN5LCBhbmQgcG9wdWxhdGlvbiBzaXplIGV2b2x2ZXMgb3ZlciB0aW1lLiBUaGUgc2l6ZSBvZiBlYWNoIHBvaW50IGlzIGRldGVybWluZWQgYnkgdGhlIHBvcHVsYXRpb24gb2YgdGhlIGNvdW50cnksIHdpdGggbGFyZ2VyIHBvaW50cyBpbmRpY2F0aW5nIGxhcmdlciBwb3B1bGF0aW9ucy4gVGhlIGNvbG9yIG9mIHRoZSBwb2ludHMgaW5kaWNhdGVzIHRoZSByZWdpb24gdG8gd2hpY2ggdGhlIGNvdW50cnkgYmVsb25ncywgYWxsb3dpbmcgdXMgdG8gc2VlIHJlZ2lvbmFsIHRyZW5kcyBhbmQgZGlmZmVyZW5jZXMgbW9yZSBjbGVhcmx5LiBCeSBvYnNlcnZpbmcgdGhlIGFuaW1hdGlvbiwgd2UgY2FuIGlkZW50aWZ5IGhvdyBlY29ub21pYyBhbmQgaGVhbHRoIG91dGNvbWVzIGhhdmUgY2hhbmdlZCBhY3Jvc3MgZGlmZmVyZW50IHJlZ2lvbnMgYW5kIHRpbWUgcGVyaW9kcywgcHJvdmlkaW5nIGluc2lnaHRzIGludG8gZ2xvYmFsIGRldmVsb3BtZW50IHBhdHRlcm5zLg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K